﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Lg.Core.Validate
{
    public class Verifier
    {
       
        #region 【自定义验证方法】
        /// <summary>
        /// 非空验证
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static bool Required(string? val)
        {
            return val != null && !string.IsNullOrEmpty(val.Trim());
        }

        /// <summary>
        /// 手机号码格式验证
        /// </summary>
        /// <param name="val">验证对像</param>
        /// <returns>bool</returns>
        public static bool IsPhone(string val)
        {
            return Regex.IsMatch(val, "^1[3-9][0-9]{9}$");
        }

        /// <summary>
        /// 邮箱格式验证
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static bool IsEmail(string val)
        {
            return Regex.IsMatch(val, @"^\w+@\w+(\.\w+)+$");
        }

        public static bool IsIdNumber(string val)
        {

            bool b = Regex.IsMatch(val, @"^[1-9][0-9]{5}([1][9][0-9]{2}|[2][0][0-9]{2})([0][1-9]|[1][0|1|2])([0][1-9]|[1|2][0-9]|[3][0|1])[0-9]{3}([0-9]|[X])$");
            if (b)
            {
                int[] weight_factor = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
                // 校验码
                string[] check_code = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
                string last = val.Last().ToString();
                string seventeen = val.Substring(0, 17);
                // ISO 7064:1983.MOD 11-2
                // 判断最后一位校验码是否正确
                char[] arr = seventeen.ToCharArray();
                int num = 0;
                for (int i = 0; i < arr.Length; i++)
                {
                    int i1 = Convert.ToInt32(arr[i].ToString());
                    int i2 = Convert.ToInt32(weight_factor[i]);
                    num = num + i1 * i2;
                }
                // 获取余数
                int resisue = num % 11;
                string last_no = check_code[resisue];
                // 返回验证结果，校验码和格式同时正确才算是合法的身份证号码
                b = last == last_no;
            }
            return b;
        }

        public static bool IsNumber(string val)
        {
            return Regex.IsMatch(val, @"^[0-9]*(\.[0-9]*)?$");
        }
        /// <summary>
        /// 是否为日期时间格式
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static bool IsDate(string val)
        {
            try
            {
                DateTime.Parse(val);
                return true;
            } catch 
            { 
                return false;
            }
          
        }
        /// <summary>
        /// 文本长度是否在指定的字数范围内
        /// </summary>
        /// <param name="val"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public static bool InRange(string val,int[] range)
        {          
            return val.Length >= range[0] && val.Length <= range[1];
        }
        /// <summary>
        /// 判断字符串是否在/不在指定的范围内
        /// </summary>
        /// <param name="val"></param>
        /// <param name="option"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public static bool InRange(string val, RangeOptions option, string[] range)
        {
            bool b= range.Contains(val);
            return option == RangeOptions.include ? b : !b;
        }
        /// <summary>
        /// 判断一个数值是否在指定的取值范围内
        /// </summary>
        /// <param name="val">验证的值</param>
        /// <param name="range"></param>
        /// <returns></returns>
        public static bool InRange(double val, double[] range)
        {
            return val>= range[0] && val<= range[1];
        }
        /// <summary>
        /// 判断数值是否在/不在指定的范围内
        /// </summary>
        /// <param name="val"></param>
        /// <param name="option"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public static bool InRange(double val, RangeOptions option, double[] range)
        {
            bool b = range.Contains(val);
            return option == RangeOptions.include ? b : !b;
        }
        /// <summary>
        /// 时间区间较验
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public static bool InRange(DateTime dt, DateTime[] range)
        {
            return dt >= range[0] && dt <= range[1];
        }
        /// <summary>
        /// 时间包含或排除一定的范围
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="option"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public static bool InRange(DateTime dt,RangeOptions option, DateTime[] range)
        {
            bool b=range.Contains(dt);
            return option == RangeOptions.include ? b : !b;
        }
        /// <summary>
        /// 强密码类型验证，8-30位，数字、大小写字母、特殊字符组合
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static bool IsStrong(string val)
        {
            return Regex.IsMatch(val, @"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\s\S]{8,30}$");
        }
        #endregion    
    }
    public enum RangeOptions
    {
        include,
        exclude
    }
}
